<script setup>
import { onMounted, onBeforeUnmount, getCurrentInstance } from "vue";
const props = defineProps({
  top: {
    type: Number,
    default: 0,
  },
  left: {
    type: Number,
    default: 0,
  },
  time: {
    type: Number,
    default: 0,
  },
});
let ctx = null;
const pointer = {
  x: 10,
  y: 10,
};
const params = {
  pointsNumber: 10,
  widthFactor: 1.5,
  mouseThreshold: 0.6,
  spring: 0.4,
  friction: 0.5,
};
const trail = [];
let timer = null;
const touchDraw = (e) => {
  console.log("e", e);

  e.preventDefault();
  pointer.x = e.touches[0].pageX - props.left;
  pointer.y = e.touches[0].pageY - props.top;

  console.log("pointer.x", pointer.x);
  console.log("pointer.y", pointer.y);

  update(true);
  timer && clearInterval(timer);
  timer = setInterval(() => {
    update(false);
  }, 20);
};
onBeforeUnmount(() => {
  timer && clearInterval(timer);
});
let canvasHeight = 0;
let canvasWidth = 0;
onMounted(() => {
  const instance = getCurrentInstance();
  let query = uni.createSelectorQuery().in(instance);
  setTimeout(() => {
    //这里用延时就可以获取真正高度，nextick也不行
    query
      .select("#canvas")
      .fields({ size: true })
      .exec((data) => {
        canvasHeight = data[0].height;
        canvasWidth = data[0].width;
      });
  }, 1000);
  ctx = uni.createCanvasContext("canvas" + props.time);
  ctx.lineCap = "round";
});
const emit = defineEmits(["onDraw"]);
const update = (isMove) => {
  if (canvasHeight <= 0) {
    //还没有初始化画布高度的话，就返回
    return;
  }
  if (trail.length === 0) {
    for (let i = 0; i < params.pointsNumber; i++) {
      trail[i] = {
        x: pointer.x,
        y: pointer.y,
        dx: 0,
        dy: 0,
      };
    }
  }
  if (pointer.y > canvasHeight) {
    pointer.y = canvasHeight;
  }
  if (pointer.y < 0) {
    pointer.y = 0;
  }
  if (pointer.x < 0) {
    pointer.x = 0;
  }
  if (pointer.x > canvasWidth) {
    pointer.x = canvasWidth;
  }

  trail.forEach((p, pIdx) => {
    const prev = pIdx === 0 ? pointer : trail[pIdx - 1];
    const spring = pIdx === 0 ? 0.4 * params.spring : params.spring;
    p.dx += (prev.x - p.x) * spring;
    p.dy += (prev.y - p.y) * spring;
    p.dx *= params.friction;
    p.dy *= params.friction;
    p.x += p.dx;
    p.y += p.dy;
  });
  if (isMove) {
    timer && clearInterval(timer);
  } else {
    if (
      Math.abs(trail[0].x - trail[params.pointsNumber - 1].x) < 0.1 &&
      Math.abs(trail[0].y - trail[params.pointsNumber - 1].y) < 0.1
    ) {
      //优化计时器
      timer && clearInterval(timer);
    }
  }
  ctx.setStrokeStyle("#FA6544");
  ctx.moveTo(trail[0].x, trail[0].y);

  for (let i = 1; i < trail.length - 1; i++) {
    const xc = 0.5 * (trail[i].x + trail[i + 1].x);
    const yc = 0.5 * (trail[i].y + trail[i + 1].y);
    ctx.quadraticCurveTo(trail[i].x, trail[i].y, xc, yc);
    ctx.lineWidth = params.widthFactor * (params.pointsNumber - i);
    ctx.stroke();
  }
  
  ctx.lineTo(trail[trail.length - 1].x, trail[trail.length - 1].y);
  ctx.stroke();
  ctx.draw();
  let value = Math.floor(((canvasHeight - pointer.y) / canvasHeight) * 100);

  console.log("value", value);

  emit("onDraw", value);
};
const clear = () => {
  ctx.clearRect(0, 0, canvasWidth, canvasHeight);
  ctx.draw();
};
defineExpose({ clear });
</script>

<template>
  <view class="draw-svg" @mousemove="touchDraw" @touchmove="touchDraw">
    <canvas :canvas-id="'canvas'" class="canvas" id="canvas"></canvas>
  </view>
</template>
<style lang="scss" scoped>
.draw-svg {
  width: 100vw;
  height: 100vh;

  canvas {
    width: 100vw;
    height: 100vh;
  }

  .canvas {
    width: 100vw;
    height: 100vh;
  }
}
</style>
